package br.com.mtg.movethegarbage.game;

import java.io.DataInputStream;
import java.io.DataOutputStream;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import br.com.mtg.movethegarbage.framework.FPSCounter;
import br.com.mtg.movethegarbage.framework.Game;
import br.com.mtg.movethegarbage.framework.Screen;
import br.com.mtg.movethegarbage.impl.GameAudio;
import br.com.mtg.movethegarbage.impl.GameFileIO;
import br.com.mtg.movethegarbage.impl.GameGraphics;
import br.com.mtg.movethegarbage.impl.GameInput;
import br.com.mtg.movethegarbage.screens.MainMenuScreen;
import br.com.mtg.movethegarbage.screens.SplashScreen;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;

public class MoveTheGarbageGame extends Activity implements Game, Renderer
{
	GameInput input;
	GameAudio audio;
	GameGraphics graphics;
	GameFileIO fileIO;
	ScoreList score;

	GLSurfaceView surface;

	Screen screen;

	FPSCounter fpsCounter;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);

		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

		surface = new GLSurfaceView(this);
		surface.setRenderer(this);
		surface.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);

		setContentView(surface);

		input = new GameInput();
		audio = new GameAudio(this);
		graphics = new GameGraphics(surface);
		fileIO = new GameFileIO(this);
		score = new ScoreList(this);

		fpsCounter = new FPSCounter();

		surface.setOnTouchListener(input);
		surface.setOnKeyListener(input);
	}

	@Override
	protected void onPause()
	{
		super.onPause();
		surface.onPause();
		if (screen != null)
			screen.pause();
	}

	@Override
	protected void onResume()
	{
		super.onResume();
		surface.onResume();
		if (screen != null)
			screen.resume();
	}

	@Override
	protected void onDestroy()
	{
		super.onDestroy();
		if (screen != null)
		{
			screen.dispose();
		}
		Assets.release();
	}

	@Override
	public void onBackPressed()
	{
		input.onBackPressed();
	}

	public void onDrawFrame(GL10 arg0)
	{
		long delta = fpsCounter.calculateDelta();
		fpsCounter.startCount();

		screen.update(delta);
		screen.present(delta);
	}

	public void onSurfaceChanged(GL10 gl, int _w, int _h)
	{
		graphics.setGL(gl);
		graphics.setSize(_w, _h);

		try
		{
			Assets.reload(this);
		}
		catch (Exception e)
		{
			Log.e("Assets:", "Could not load resources", e);
		}
		if (screen != null)
			screen.resume();
	}

	public void onSurfaceCreated(GL10 gl, EGLConfig conf)
	{
		graphics.setGL(gl);

		if (screen == null)
		{
			screen = new SplashScreen(this);
			try
			{
				Assets.load(this);
			}
			catch (Exception e)
			{
				Log.e("Assets:", "Could not load resources", e);
			}
		}
		else
		{
			try
			{
				Assets.reload(this);
			}
			catch (Exception e)
			{
				Log.e("Assets:", "Could not load resources");
			}
		}

		fpsCounter.startCount();
	}

	public Screen getCurrentScreen()
	{
		return screen;
	}

	public Screen getStartScreen()
	{
		return new MainMenuScreen(this);
	}

	public void setScreen(Screen _screen)
	{
		if (screen != null)
		{
			screen.pause();
			screen.dispose();
			synchronized (input)
			{
				input.getKeyEvents().clear();
				input.getTouchEvents().clear();
				input.wasBackPressed();
			}
		}

		screen = _screen;

		screen.resume();
		screen.update(0);
	}

	public GameInput getInput()
	{
		return input;
	}

	public GameAudio getAudio()
	{
		return audio;
	}

	public GameGraphics getGraphics()
	{
		return graphics;
	}

	public GameFileIO getFileIO()
	{
		return fileIO;
	}

	public void exit(int i)
	{
		this.finish();
	}

	public String getStringFromResource(int id)
	{
		return this.getResources().getString(id);
	}

	public ScoreList getScore()
	{
		return score;
	}

	public int loadProgress() throws Exception
	{
		if (fileIO.checkIfExists("Save.mtg"))
		{
			DataInputStream input = new DataInputStream(fileIO.readFile("Save.mtg"));
			return input.readInt();
		}
		else
		{
			saveProgress(0);
			return 0;
		}
	}

	public void saveProgress(int progress) throws Exception
	{
		DataOutputStream output = new DataOutputStream(fileIO.writeFile("Save.mtg", false));
		output.writeInt(progress);
	}

	public FPSCounter getFPS()
	{
		return fpsCounter;
	}
}
